package com.veetao.api.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import redis.clients.jedis.JedisCluster;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service("redisService")
public class RedisService {

	@Resource
	JedisCluster jedisClusterTemplate;
	static ObjectMapper objMapper = new ObjectMapper();

	private static Logger logger = Logger.getLogger(RedisService.class);

	public static final String REDIS_KEY_DATA = "EXPRESSION_DATA";
	// 更新时间排序的list id
	public static final String REDIS_KEY_DATA_ID = "EXPRESSION_DATA_ID";
	// 点赞排序的list id
	public static final String REDIS_KEY_SORT_D_ID = "EXPRESSION_D_ID";
	// 推荐值排序的list id
	public static final String REDIS_KEY_SORT_R_ID = "EXPRESSION_R_ID";
	// 推荐值排序的map
	public static final String REDIS_KEY_SORT_R_DATA = "EXPRESSION_R_DATA";

	public boolean exists(String... keys) {
		for (String key : keys) {
			if (!jedisClusterTemplate.exists(key)) {
				return false;
			}
		}
		return true;
	}

	// 添加有序列表
	public int zadd(String key, Map<String, Double> scoreMembers) {
		int ct = 0;
		if (StringUtils.isNotEmpty(key) && null != scoreMembers
				&& scoreMembers.size() > 0) {
			long index = jedisClusterTemplate.zadd(key, scoreMembers);
			if (index > 0)
				ct++;
		}

		return ct;
	}

	public int zadd(String key, String member, Double scoreMember) {
		int ct = 0;
		if (StringUtils.isNotEmpty(key) && null != scoreMember
				&& StringUtils.isNotEmpty(member)) {
			long index = jedisClusterTemplate.zadd(key, scoreMember, member);
			if (index > 0)
				ct++;
		}

		return ct;
	}

	// 获取有序集合的score
	public Double zscore(String key, String zkey) {
		if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(zkey)) {
			return jedisClusterTemplate.zscore(key, zkey);
		}
		return null;
	}

	public Long zrem(String key, String member) {
		if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(member)) {
			return jedisClusterTemplate.zrem(key, member);
		}

		return null;
	}

	public <T> String set(String key, T t) {
		try {
			if (StringUtils.isNotEmpty(key) && null != t)
				return jedisClusterTemplate.set(key,
						objMapper.writeValueAsString(t));
		} catch (JsonProcessingException e) {
			logger.error(e);
		}

		return null;
	}

	public String set(String key, String str) {
		if (StringUtils.isNotEmpty(key) && null != str)
			return jedisClusterTemplate.set(key, str);
		return null;
	}

	public <T> T get(String key, Class<T> clazz) {
		String str = null;
		if (StringUtils.isNotEmpty(key) && null != clazz)
			str = jedisClusterTemplate.get(key);
		try {
			if (StringUtils.isNotEmpty(str))
				return objMapper.readValue(str, clazz);
		} catch (JsonParseException e) {
			logger.error(e);
		} catch (JsonMappingException e) {
			logger.error(e);
		} catch (IOException e) {
			logger.error(e);
		}

		return null;
	}

	public String get(String key) {
		if (StringUtils.isNotEmpty(key))
			return jedisClusterTemplate.get(key);
		return null;
	}

	public <T> List<T> hmget(String key, Class<T> clazz, String... ids) {
		List<T> results = null;
		if (StringUtils.isNotEmpty(key) && null != clazz && null != ids
				&& ids.length > 0) {
			List<String> vals = jedisClusterTemplate.hmget(key, ids);
			if (null != vals && vals.size() > 0) {
				for (String val : vals) {
					try {
						if (StringUtils.isNotEmpty(val)) {
							T t = objMapper.readValue(val, clazz);
							if (null != t) {
								if (null == results)
									results = new ArrayList<T>();
								results.add(t);
							}
						}
					} catch (JsonParseException e) {
						logger.error(e);
					} catch (JsonMappingException e) {
						logger.error(e);
					} catch (IOException e) {
						logger.error(e);
					}
				}
			}
		}

		return results;
	}

	public Map<String, String> hgetAll(String key) {
		if (StringUtils.isNotEmpty(key)) {
			return jedisClusterTemplate.hgetAll(key);
		}
		return null;
	}

	public boolean hexists(String key, String field) {
		if (StringUtils.isNotEmpty(key)) {
			return jedisClusterTemplate.hexists(key, field);
		}
		return false;
	}

	public <T> String hmset(String key, Map<String, T> objs) {
		if (null != key && null != objs && objs.size() > 0) {
			Map<String, String> map = new HashMap<String, String>();
			for (String k : objs.keySet()) {
				T t = objs.get(k);
				try {
					map.put(k, objMapper.writeValueAsString(t));
				} catch (JsonProcessingException e) {
					logger.error(e);
				}
			}
			if (null != map && map.size() > 0)
				return jedisClusterTemplate.hmset(key, map);
		}

		return null;
	}

	public Long hset(String key, String hkey, String value) {
		if (StringUtils.isNotEmpty(key)) {
			return jedisClusterTemplate.hset(key, hkey, value);
		}
		return null;
	}

	public <T> Long hset(String key, String hkey, Class<T> clazz, T t) {
		if (StringUtils.isNotEmpty(key) && null != clazz && null != t) {
			String value = null;
			try {
				value = objMapper.writeValueAsString(t);
				return jedisClusterTemplate.hset(key, hkey, value);
			} catch (JsonProcessingException e) {
				logger.error(e);
			}
		}

		return null;
	}

	public <T> T hget(String key, String hkey, Class<T> clazz) {

		String str = null;
		if (StringUtils.isNotEmpty(key) && null != clazz)
			str = jedisClusterTemplate.hget(key, hkey);
		try {
			if (StringUtils.isNotEmpty(str))
				return objMapper.readValue(str, clazz);
		} catch (JsonParseException e) {
			logger.error(e);
		} catch (JsonMappingException e) {
			logger.error(e);
		} catch (IOException e) {
			logger.error(e);
		}

		return null;
	}

	public Long hdel(String key, String hkey) {
		if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(hkey))
			return jedisClusterTemplate.hdel(key, hkey);

		return null;
	}

	public Long zcount(String key, Double min, Double max) {
		if (StringUtils.isNotEmpty(key) && null != min && null != max)
			return jedisClusterTemplate.zcount(key, min, max);

		return null;
	}

	public Set<String> zrevrange(String key, Long start, Long end) {
		if (StringUtils.isNotEmpty(key) && null != start && null != end)
			return jedisClusterTemplate.zrevrange(key, start, end);
		return null;
	}

	public Long zrevrank(String key, String member) {

		if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(member)) {
			return jedisClusterTemplate.zrevrank(key, member);
		}
		return null;
	}

	public Set<String> zrevrangeByScore(String key, Double max, Double min,
			int offset, int count) {
		if (StringUtils.isNotEmpty(key) && null != min && null != max)
			return jedisClusterTemplate.zrevrangeByScore(key, max, min, offset,
					count);
		return null;
	}
	
	public Set<String> zrangeByScore(String key, Double max, Double min) {
		if (StringUtils.isNotEmpty(key) && null != min && null != max)
			return jedisClusterTemplate.zrangeByScore(key, max, min);
		return null;
	}

	public Double zincrby(String key, String member, Double score) {
		if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(member)
				&& null != score)
			return jedisClusterTemplate.zincrby(key, score, member);
		return null;
	}

	public Long zrank(String key, String member) {
		if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(member))
			return jedisClusterTemplate.zrank(key, member);
		return null;
	}

	public Long zcount(String key, String min, String max) {
		if (StringUtils.isNotEmpty(key))
			return jedisClusterTemplate.zcount(key, min, max);
		return null;
	}

	public Long del(String key) {
		if (StringUtils.isNotEmpty(key))
			return jedisClusterTemplate.del(key);
		return null;
	}
	
	public void expire(String key, int seconds){
		if (StringUtils.isNotEmpty(key))
			jedisClusterTemplate.expire(key, seconds);
	}
	
}